;BARRY ZARUCKI M0DGQ AIRBAND VCO CONTROLLER ;8.333kHz CHANEL SPACING ;EXTRA ADD/SUBTRACT ROUTINE FOR DISPLAY REGISTERS ;FREQUENCY DISPLAYED ON LCD ;OPTICAL OR MECHANICAL ROTARY ENCODER INCREMENTS/DECREMENTS 16 BIT WORD USING TWO 8 BIT REGISTERS ;WHICH IS THEN SENT AS SERIAL DATA. ;ENCODER "PRESCALER" INCLUDED TO SET REGISTER INC/DEC BY NUMBER OF ENCODER TRANSITIONS in this case 4. USE 60 FOR OPTICAL ENCODER ( 100 PULSES PER REV ) ;ENCODER NOW HAS MAX AND MIN BAND EDGE 110 mhZ - 136 mhZ ;16 BIT SERIAL ROUTINE ;PUSH BUTTON TUNE STEP SELECT - 3 TUNE STEPS AVAILABLE 8.33k,100k, 1MHz ;NOW FIVE MEMORIES ;CORRECT LOAD SEQUENCE FOR MC145170 ;CHANGED I/O FOR NEW PCB ;FIXED MEMORY RECALL ISSUE ;LAST USED FREQUENCY SAVE ON ROTARY AND MEMORY ;******************************************************************************************************************** LIST p=16F628A ;tell assembler what chip we are using INCLUDE "P16F628A.inc" ;include the defaults for the chip __CONFIG 0x3F18 ;sets the configuration settings ;INT 4mhZ OSC ;************************************************************************************************************** CBLOCK 0x020 TEMP_0 ;TEMP VARIABLE USED FOR COMPARISONS OF OLD AND NEW ENCODER READINGS (XOR). OLD ;OLD (PREVIOUS) ENCODER VALUE NEW ;NEW (LATEST) ENCODER VALUE. DIV_COUNT_DOWN ;4 TRANSISTION DOWN REG * SOME ENCODERS PRODUCE FOUR TRANSITIONS PER INDENT DIV_COUNT_UP ;4 TRANSITION UP REG * VAR_LO ;SYNTH FREQUENCY WORD BYTE LO REGISTER VAR_HI ;SYNTH FREQUENCY WORD BYTE HI REGISTER BYTE_0 ;BYTE_0 TO BE SENT VIA SERIAL - TRANSFERED FROM VAR_LO BYTE_1 ;BYTE_1 TO BE SENT VIA SERIAL - TRANSFERED FROM VAR_HI BIT_COUNT0 ;NUMBER OF BITS TO SEND BIT_COUNT1 ;NUMBER OF BITS TO SEND DLY_COUNT1 ;SWITCH BOUNCE COUNTER DELAY REG DLY_COUNT2 ; " " " " " STEP_BYTE_LO ;REGISTER TO CONTAIN TUNING STEP VALUE STEP_BYTE_HI ;REGISTER TO CONTAIN TUNING STEP VALUE BUTT_COUNT ;STEP BUTTON COUNTER MBUTT_COUNT ;MEMORY SELECT BUTTON COUNTER MS_BUTT_COUNT DISPLAY_STEP_BYTE_HI ;DISPLAY STEP BYTE HI REGISTER DISPLAY_STEP_BYTE_LO ;DISPLAY STEP BYTE LO REGISTER DISPLAY_VAR_LO ;DISPLAY VARIABLE LO TO SEND TO LCD DISPLAY_VAR_HI ;DISPLAY VARIABLE HI TO SEND TO LCD ST_VAR_LO ;TEMP REG FOR ST_VAR_LO ST_VAR_HI ;TEMP REG ENDSTOP_MAX_LO ;TEMP REG ENDSTOP_MAX_HI ;TEMP REG ENDSTOP_MIN_LO ;TEMP REG ENDSTOP_MIN_HI ;TEMP REG F_EE_ADR_LO ;EPROM ADDRESS REGISTERS F_EE_ADR_HI ; D_EE_ADR_LO ; D_EE_ADR_HI ; DLY_COUNT6 ; DLY_COUNT7 ; DELAY COUNTERS FOR MEMORY SAVE ROUTINE DLY_COUNT8 ; count ;used in looping routines dly_count3 ;used in delay routine dly_count4 ;used in delay routine dly_count5 ;used in delay routine dly_count6 ; dly_count7 ; tmp1 ;temporary storage tmp2 templcd ;TEMP STORE FOR 4 BIT MODE templcd2 CONVERT_BYTE_LO ;Binary inputs for decimal convert routine CONVERT_BYTE_HI TenK ;Decimal outputs from convert routine Thou Hund Tens Ones endc ;END OF DATA MEMORY ;*************************************************************************** ORG 0x0000 ;org sets the origin, 0x0000 for the 16F628, GOTO START ;this is where the program starts running ;*************************************************************************** #DEFINE ENCODER PORTB ;ENCODER INPUTS BIT 0 AND 1 #DEFINE SDATA PORTB,2 ;MAKE OUTPUT #DEFINE CLOCK PORTB,3 ;MAKE OUTPUT #DEFINE LATCH PORTB,4 ;MAKE OUTPUT #DEFINE STEP_B PORTB,6 ;TUNING STEP BUTTON #DEFINE MEM1 PORTB,5 ;MEMORY RECALL SELECT BUTTON #DEFINE MEM2 PORTB,7 ;MEMORY SELECT LOCATION SAVE BUTTON #DEFINE MEM3 PORTA,5 ;MEMORY DONE (SAVE) BUTTON #DEFINE LCD_PORT PORTA #DEFINE LCD_RS PORTA,4 #DEFINE LCD_RW PORTA,6 #DEFINE LCD_E PORTA,7 ;********************************************************************** START errorlevel -302, -305 MOVLW 0x07 ;LOAD 0x07 INTO W MOVWF CMCON ;TURN COMPARATORS OFF CLRF PORTA ;CLEAR PORTA CLRF PORTB ;CLEAR PORTB CLRF count BANKSEL TRISA ;SELECT BANK1 MOVLW b'00100000' ;SET PORTA, BITS 0,1 AND 2 ARE OUTPUTS REST INPUTS MOVWF TRISA ; MOVLW b'11100011' ; MOVWF TRISB ; BANKSEL PORTA ;SELECT BANK0 MOVLW b'00000001' ;LOAD STEP_BYTE_LO "1" MOVWF STEP_BYTE_LO MOVLW b'00000000' ;LOAD STEP_BYTE_HI MOVWF STEP_BYTE_HI MOVLW b'00001000' ;LOAD DISPLAY_STEP_BYTE_LO "8" MOVWF DISPLAY_STEP_BYTE_LO MOVLW b'00000000' ;LOAD DISPLAY_STEP_BYTE_HI MOVWF DISPLAY_STEP_BYTE_HI MOVLW .4 ;ENCODER "PRE-SCALE" VALUE MOVWF DIV_COUNT_DOWN ; MOVWF DIV_COUNT_UP ; MOVLW .3 MOVWF BUTT_COUNT ;LOAD BUTTON COUNTER MOVLW .5 MOVWF MBUTT_COUNT ;LOAD MEMORY BUTTON COUNTER MOVLW .5 MOVWF MS_BUTT_COUNT MOVLW b'00111011' ;136 MHz (+10.7 MHZ IF) UPPER BAND EDGE, (65535-17604 = 47931) , DETERMINED BY: SUBTRACING 17604 (146.7/0.0083333) FROM 11111111 11111111 MOVWF ENDSTOP_MAX_LO MOVLW b'10111011' ;136 MHz MOVWF ENDSTOP_MAX_HI MOVLW b'10010100' ;110 MHz (+10.7 MHz IF)LOWER BAND EDGE, (120.7 MHZ/0.0083333 kHz) MOVWF ENDSTOP_MIN_LO MOVLW b'00111000' ;110 MHz MOVWF ENDSTOP_MIN_HI MOVLW 0x00 ;FREQUENCY START UP EEPROM ADDRESS LO (* 0x6C for 25kHz spacing - old code) 44 8.333kHz new THESE ARE THE HEX VALUES FOR START UP MOVWF F_EE_ADR_LO ; MOVLW 0x01 ;FREQUENCY START UP EEPROM ADDRESS HI (* 0x14 for 25kHz spacing - old code) 3D 8.333kHz new FREQUENCY OF 120MHz MOVWF F_EE_ADR_HI MOVLW 0x40 ;DISPLAY START UP EEPROM ADDRESS LO * 0x20 THESE ARE THE HEX VALUES FOR LCD MOVWF D_EE_ADR_LO ; MOVLW 0x41 ;DISPLAY START UP EEPROM ADDRESS HI * 0x4E START FREQUENCY DISPLAY OF 120 MHz MOVWF D_EE_ADR_HI ; ; THESE MUST BE LOADED INTO EPROM CALL FREQ_EREAD ;START UP FREQUECY LOADED FROM EPROM CALL DISP_EREAD ;START UP DISPLAY LOADED FROM EPROM WHEN PROGRAMING PIC FOR FIRST TIME CALL IN_MC ; INITIALISE SYNTH CHIP ;************************************************************************************ ;LOAD SYNTH C AND R REGISTERS MOVLW .8 ;SET BIT_COUNT1 FOR 8 BITS MOVWF BIT_COUNT0 ; MOVLW b'00110011' ;SYNTH C REGISTER VALUE MOVWF BYTE_0 ; BCF LATCH BCF STATUS,C ;CLEAR CARRY ETC LOOPC RLF BYTE_0,F ;ROTATE BYTE_0 LEFT BY ONE BIT BTFSS STATUS,C ;DOES CARRY = 1? BCF SDATA ;NO,SET SDATA TO 0 BTFSC STATUS,C ;DOES CARRY= 0? BSF SDATA ;NO, SO SET SDATA TO 1 BSF CLOCK ;GENERATE ONE CLOCK NOP ;SETTLE TIME BCF CLOCK ;CLEAR CLOCK DECFSZ BIT_COUNT0 ;HAVE ALL BITS OF BYTE 0 BEEN SENT? GOTO LOOPC ;IF NOT REPEAT BSF LATCH ;SET LATCH TO 1 CALL Delay3 ;************************************************************ MOVLW .7 ;SET BIT_COUNT0 FOR 7 BITS - R REGISTER 15 BITS ONLY, MSB IS LOADED FIRST MOVWF BIT_COUNT0 ; MOVLW b'00000010' ;R REG HI BYTE, SYNTH CHIP WILL SEE MSB AS '0000001' AS WE ARE ONLY SENDING SEVEN BITS MOVWF BYTE_0 ; MOVLW .8 ;SET BIT_COUNT1 FOR 8 BITS MOVWF BIT_COUNT1 ; MOVLW b'11100000' ;R REG LOW BYTE 8.333kHZ CHANEL SPACING (4MHz ref frequency/0.008333kHz) MOVWF BYTE_1 ; BCF LATCH BCF STATUS,C ;CLEAR CARRY ETC LOOPR_HI RLF BYTE_0,F ;ROTATE BYTE_0 LEFT BY ONE BIT BTFSS STATUS,C ;DOES CARRY = 1? BCF SDATA ;NO,SET SDATA TO 0 BTFSC STATUS,C ;DOES CARRY= 0? BSF SDATA ;NO, SO SET SDATA TO 1 BSF CLOCK ;GENERATE ONE CLOCK NOP ;SETTLE TIME BCF CLOCK ;CLEAR CLOCK DECFSZ BIT_COUNT0 ;HAVE ALL BITS OF BYTE 0 BEEN SENT? GOTO LOOPR_HI ;IF NOT REPEAT LOOPR_LO RLF BYTE_1,F ;ROTATE BYTE_1 LEFT BY ONE BIT BTFSS STATUS,C ;DOES CARRY = 1? BCF SDATA ;NO,SET SDATA TO 0 BTFSC STATUS,C ;DOES CARRY= 0? BSF SDATA ;NO, SO SET SDATA TO 1 BSF CLOCK ;GENERATE ONE CLOCK NOP ;SETTLE TIME BCF CLOCK ;CLEAR CLOCK DECFSZ BIT_COUNT1 ;HAVE ALL BITS OF BYTE 1 BEEN SENT? GOTO LOOPR_LO ;IF NOT REPEAT BSF LATCH ;SET LATCH TO 1 CALL Delay3 ;**************************************************************************************************** ;Get intitial input from ENCODER & put the value in OLD. MOVF ENCODER,W MOVWF OLD ;Strip off all but the 2 LSBs in OLD. MOVLW B'00000011' ;Create bit mask for 2 LSBs (bits 0 & 1). ANDWF OLD,F ;Zero bits 7 to 2. CALL LCD_Init CALL LCD_Line1_MHz ;"MHz" TO SHOW ON LCD ON START UP MOVLW ' ' CALL LCD_Char MOVLW 'M' CALL LCD_Char MOVLW 'H' CALL LCD_Char MOVLW 'z' CALL LCD_Char MOVLW ' ' CALL LCD_Line2 ;"STEP" (CHANNEL SPACING) TO SHOW ON LCD ON START UP MOVLW 'S' CALL LCD_Char MOVLW 'T' CALL LCD_Char MOVLW 'E' CALL LCD_Char MOVLW 'P' CALL LCD_Char CALL KHZ8.3 ;START UP CHANNEL SPACING TO SHOW ON LCD CALL VFO ;"VFO" TO SHOW ON LCD ON START UP CALL SERIAL ;SEND START UP FREQUENCY TO SYNTH CHIP CALL SEND_LCD ;SEND START UP DISPLAY TO LCD ;***************************************************************************** MAIN CALL ENCODER_CHECK ;has encoder moved? CALL CONVERT ;convert to decimal CALL CHECK ;check display digits CALL SEND_LCD ;update LCD CALL BUTTON_TEST ;memory buttons test CALL BUTTON_TEST2 ; CALL BUTTON_TEST3 ; GOTO MAIN ;go to begining of loop ;******************************************************************************** ENCODER_CHECK MOVF ENCODER,W MOVWF NEW ;MASK OF BITS 0 AND 1 IN NEW. MOVLW b'00000011' ;Create bit mask for 2 BITS (bits 0 & 1). ANDWF NEW,F ;Zero all bits apart from 0 and 1. ;Compare previous encoder inputs (OLD) with latest ones (NEW). MOVF NEW,W ;Move the contents of NEW to TEMP and OLD to W MOVWF TEMP_0 ;in order to compare them with XOR. MOVF OLD,W XORWF TEMP_0,F ;XOR previous inputs (in W) with latest inputs ;(in TEMP) to see if they are equal. BTFSC STATUS,Z ;Test result and skip next line if status zero bit is 0. GOTO Rtrn ;Status zero bit is 1. Previous inputs equal latest ;inputs. Rotary encoder did not move. Return ;to loop. ;STATUS ZERO BIT IS 0. ROTARY ENCODER MOVED. DETERMINE DIRECTION. BCF STATUS,C ;Clear the carry bit in the status register and RLF OLD,F ;left shift it into OLD to align bit 1 of OLD ;with bit 0 of NEW. MOVF NEW,W ;Move the contents of NEW to W in order to XOR. XORWF OLD,F ;XOR previous inputs (in OLD) with latest ;inputs (in W) to determine CW or CCW. BTFSC OLD,1 ;Test bit 1 of result (in OLD). Skip next line ;if it is 0 (direction is CCW). GOTO Up ;Bit is 1 (direction is CW). Go around Down ;and increment counter. Down ;Decrements VAR because encoder moved CCW. DECFSZ DIV_COUNT_DOWN ;HAVE 4/60 TRANSITIONS ELLAPSED,I.E. ONE STEP ON ROTARY? GOTO CONTINUE ;NO MOVF VAR_LO,W MOVWF ST_VAR_LO ;TEMP STORE REGISTER FOR VAR_LO MOVF VAR_HI,W MOVWF ST_VAR_HI ;TEMP STORE REGISTER FOR VAR_HI ;SUBTRACT STEP_BYTE FROM ST_VAR TO GET NEW FREQUENCY MOVF STEP_BYTE_LO,W ; Get low byte of STEP_BYTE SUBWF ST_VAR_LO,F ; SUBTRACT STEP_BYTE_LO FROM VAR_LO, leave result in VAR_LO MOVF STEP_BYTE_HI,W ; Now get high byte of STEP_BYTE BTFSS STATUS,C ; If there was a borrow, rather than INCFSZ STEP_BYTE_HI,W ; decrement high byte of dst we inc src SUBWF ST_VAR_HI,F ; Subtract the high byte of STEP_BYTE_HI from VAR_HI, leave result in VAR_HI ; THE FOLLOWING ROUTINE CHECKS IF WE HAVE REACHED LOWER ENDSTOP (BAND EDGE)ENDSTOP MIN IS SUBTRACTED FROM ST_VAR, IF A BORROW OCCURS THEN NO DECREMENT. MOVF ENDSTOP_MIN_LO,W ; Get HI byte of endstop MINIMUM SUBWF ST_VAR_LO,F ; Add to destination MOVF ENDSTOP_MIN_HI,W ; Get high byte BTFSS STATUS,C ; Check for carry INCFSZ ENDSTOP_MIN_HI,W ; Add one for carry SUBWF ST_VAR_HI,F ; Add high byte into DST BTFSC STATUS,C ;TEST FOR CARRY (BORROW) GOTO DEC ;NO CARRY SO ENDSTOP NOT REACHED CARRY ON WITH DECREMENT ROUTINE GOTO NOSUB ;CARRY SO ENDSTOP REACHED NO DECREMENT ROUTINE DEC CALL SUB ;UPDATE SERIAL SYNTH DATA CALL SUB_2 ;UPDATE DISPLAY DATA CALL SERIAL CALL LFU_SAVE ;SAVE FREQUENY AND DISPLAY WORDS TO EPROM BOOT UP MEMORY LOCATION NOSUB MOVLW .4 ;ENCODER "PRE-SCALE" VALUE MOVWF DIV_COUNT_DOWN ;RELOAD COUNTER FOR NEXT TIME GOTO CONTINUE ;BRANCH AROUND UP. Up ;Increments VAR because encoder moved CW. DECFSZ DIV_COUNT_UP ;HAVE 4/60TRANSITIONS ELLAPSED,I.E. ONE STEP ON ROTARY?; GOTO CONTINUE ;NO MOVF VAR_LO,W MOVWF ST_VAR_LO ;TEMP STORE REGISTER FOR VAR_LO MOVF VAR_HI,W MOVWF ST_VAR_HI ;TEMP STORE REGISTER FOR VAR_HI ;ADD STEP_BYTE TO ST_VAR TO GET NEW FREQUENCY MOVF STEP_BYTE_LO,W ; Get low byte of STEP_BYTE ADDWF ST_VAR_LO,F ; Add to ST_VAR_LO,leave result in ST_VAR_LO MOVF STEP_BYTE_HI,W ; Get high byte of STEP_BYTE BTFSC STATUS,C ; Check for carry INCFSZ STEP_BYTE_HI,W ; Add one for carry ADDWF ST_VAR_HI,F ; Add high byte into ST_VAR_HI,leave result in ST_VAR_HI ; THE FOLLOWING ROUTINE CHECKS IF WE HAVE REACHED UPPER ENDSTOP (BAND EDGE). ST_VAR IS ADDED TO ENDSTOP MAX, IF CARRY OCCURS THEN NO INCREMENT MOVF ENDSTOP_MAX_LO,W ; Get low byte of endstop MAXIMUM ADDWF ST_VAR_LO,F ; Add to destination MOVF ENDSTOP_MAX_HI,W ; Get high byte of endstop MAXIMUM BTFSC STATUS,C ; Check for carry INCFSZ ENDSTOP_MAX_HI,W ; Add one for carry ADDWF ST_VAR_HI,F ; Add high byte into DST BTFSS STATUS,C ;TEST FOR CARRY OUT GOTO INC ;RESULT NO CARRY OUT, SO CONTINUE WITH INCREMENT ROUTINE GOTO NOADD ;RESULT CARRY OUT 1, ENDSTOP REACHED SO NO INCREMENT ROUTINE INC CALL ADD ;UPDATE SERIAL SYNTH DATA CALL ADD_2 ;UPDATE DISPLAY DATA CALL SERIAL CALL LFU_SAVE ;SAVE FREQUENY AND DISPLAY WORDS TO EPROM BOOT UP MEMORY LOCATION NOADD MOVLW .4 ;ENCODER "PRE-SCALE" VALUE MOVWF DIV_COUNT_UP ;RELOAD COUNTER FOR NEXT TIME CONTINUE MOVF NEW,W ;SAVE NEW ENCODER READING TO OLD MOVWF OLD CALL VFO Rtrn RETURN ;**************************************************************************************** ;16 BIT SERIAL SEND ROUTINE FOR N COUNTER SERIAL MOVLW .8 ;SET BIT_COUNT0 FOR 8 BITS MOVWF BIT_COUNT0 ; MOVF VAR_HI,W ;MOVE VAR_HI INTO BYTE_0 MOST SIGNIFICANT BYTE LOADED INTO SYNTH FIRST MOVWF BYTE_0 ; MOVLW .8 ;SET BIT_COUNT1 FOR 8 BITS MOVWF BIT_COUNT1 ; MOVF VAR_LO,W ;MOVE VAR_LO INTO BYTE_1 LEAST SIGNIFICANT BYTE LOADED LAST INTO SYNTH MOVWF BYTE_1 ; BCF LATCH BCF STATUS,C ;CLEAR CARRY ETC LOOP1 RLF BYTE_0,F ;ROTATE BYTE_0 LEFT BY ONE BIT BTFSS STATUS,C ;DOES CARRY = 1? BCF SDATA ;NO,SET SDATA TO 0 BTFSC STATUS,C ;DOES CARRY= 0? BSF SDATA ;NO, SO SET SDATA TO 1 BSF CLOCK ;GENERATE ONE CLOCK NOP ;SETTLE TIME BCF CLOCK ;CLEAR CLOCK DECFSZ BIT_COUNT0 ;HAVE ALL BITS OF BYTE 0 BEEN SENT? GOTO LOOP1 ;IF NOT REPEAT LOOP2 RLF BYTE_1,F ;ROTATE BYTE_1 LEFT BY ONE BIT BTFSS STATUS,C ;DOES CARRY = 1? BCF SDATA ;NO,SET SDATA TO 0 BTFSC STATUS,C ;DOES CARRY= 0? BSF SDATA ;NO, SO SET SDATA TO 1 BSF CLOCK ;GENERATE ONE CLOCK NOP ;SETTLE TIME BCF CLOCK ;CLEAR CLOCK DECFSZ BIT_COUNT1 ;HAVE ALL BITS OF BYTE 1 BEEN SENT? GOTO LOOP2 ;IF NOT REPEAT BSF LATCH ;SET LATCH TO 1 CALL Delay3 ;SETTLE TIME RETURN ;***************************************************************************************** ;SUBTRACT TUNING STEP FROM VAR_ HI/LO, RESULT IN VAR_ HI/LO SUB MOVF STEP_BYTE_LO,W ; Get low byte of subtrahend SUBWF VAR_LO,F ; SUBTRACT DISPLAY_STEP_BYTE_LO FROM DISPLAY_VAR_LO MOVF STEP_BYTE_HI,W ; Now get high byte of subtrahend BTFSS STATUS,C ; If there was a borrow, rather than INCFSZ STEP_BYTE_HI,W ; decrement high byte of dst we inc src SUBWF VAR_HI,F ; Subtract the high byte and we're done RETURN ;************************************************************************************** ;SUBTRACT DISPLAY STEP FROM DISPLAY_VAR_ HI/LO, RESULT IN DISPLAY_VAR_ HI/LO SUB_2 MOVF DISPLAY_STEP_BYTE_LO,W ; Get low byte of subtrahend SUBWF DISPLAY_VAR_LO,F ; SUBTRACT DISPLAY_STEP_BYTE_LO FROM DISPLAY_VAR_LO MOVF DISPLAY_STEP_BYTE_HI,W ; Now get high byte of subtrahend BTFSS STATUS,C ; If there was a borrow, rather than INCFSZ DISPLAY_STEP_BYTE_HI,W ; decrement high byte of dst we inc src SUBWF DISPLAY_VAR_HI,F ; Subtract the high byte and we're done RETURN ;********************************************************************************* ;ADD TUNING STEP TO VAR_ HI/LO, RESULT IN VAR_ HI/LO ADD MOVF STEP_BYTE_LO,W ; Get low byte ADDWF VAR_LO,F ; Add to destination MOVF STEP_BYTE_HI,W ; Get high byte BTFSC STATUS,C ; Check for carry INCFSZ STEP_BYTE_HI,W ; Add one for carry ADDWF VAR_HI,F ; Add high byte into DST RETURN ;****************************************************************************** ADD_2 MOVF DISPLAY_STEP_BYTE_LO,W ; Get low byte ADDWF DISPLAY_VAR_LO,F ; Add to destination MOVF DISPLAY_STEP_BYTE_HI,W ; Get high byte BTFSC STATUS,C ; Check for carry INCFSZ DISPLAY_STEP_BYTE_HI,W ; Add one for carry ADDWF DISPLAY_VAR_HI,F ; Add high byte into DST RETURN ;************************************************************************************* ; A LITTLE BIT OF TRICKERY HERE TO KEEP DISPLAY IN SYNC AS WE ARE NOT DISPLAYING FRACTIONS OF kHz (0.33333 AND MULTIPLES OF) CHECK MOVLW .4 ;TEST Ones in convert data, if showing a 4 then we will change this to a 5 and inc DISPLAY_VAR_LO to display a 5 XORWF Ones,W BTFSS STATUS,Z GOTO $+4 INCF Ones INCF DISPLAY_VAR_LO GOTO CHECK_DONE MOVLW .9 ;TEST Ones in convert data, if showing a 9 then we will change this to a 0 and increment Tens also inc DISPLAY_VAR_LO to display 100 instead of 99 XORWF Ones,W BTFSS STATUS,Z GOTO $+5 CLRF Ones INCF Tens INCF DISPLAY_VAR_LO GOTO CHECK_DONE MOVLW .2 ;Test Ones in convert data, if showing a 2 then we will change this to a 1 XORWF Ones,W BTFSS STATUS,Z GOTO $+4 DECF Ones DECF DISPLAY_VAR_LO GOTO CHECK_DONE MOVLW .7 ;;Test Ones in convert data, if showing a 7 then we will change this to a 6 XORWF Ones,W BTFSS STATUS,Z GOTO $+3 DECF Ones DECF DISPLAY_VAR_LO CHECK_DONE RETURN ;**************************************************************************************** ;TUNING STEP SELECT BUTTON BUTTON_TEST BTFSS STEP_B ;CHECK IF UP BUTTON PRESSED GOTO RTN ;NO, SO CHECK IF DOWN BUTTON PRESSED CALL DELAY ;WAIT FOR SWITCH BOUNCE BTFSS STEP_B ;VALID PRESS SKIP NEXT INSTRUCTION GOTO RTN ;INVALID PRESS, GO CHECK BUTTON DOWN BTFSC STEP_B ;HAS BUTTON BEEN RELEASED? GOTO $-1 ;NO CALL DELAY ;YES, WAIT FOR SWITCH BOUNCE BTFSC STEP_B ;BOUNCE OVER? GOTO $-4 ;NO DECFSZ BUTT_COUNT ;DECREMENT BUTT_COUNT (TUNING STEP SELECT BUTTON) GOTO STEP1 MOVLW .3 ;LOAD COUNTER FOR NEXT TIME (THREE TUNING STEPS) MOVWF BUTT_COUNT STEP1 MOVLW .1 XORWF BUTT_COUNT,W ;COMPARE NUMBER OF BUTTON PRESSES BTFSS STATUS,Z ;IF XOR RESULT ZERO THEN SKIP NEXT INSTRUCTION GOTO STEP2 ;XOR RESULT NOT ZERO SO GOTO NEXT TUNE STEP MOVLW b'01111000' ;LOAD TUNING STEP LO BYTE ;1MHz ;120 MOVWF STEP_BYTE_LO MOVLW b'00000000' ;LOAD TUNING STEP LO BYTE ; (1000kHz/0.0083333 = 120) MOVWF STEP_BYTE_HI MOVLW b'11101000' ;LOAD TUNING STEP DISPLAY (LCD DATA) LO BYTE MOVWF DISPLAY_STEP_BYTE_LO MOVLW b'00000011' ;LOAD TUNING STEP DISPLAY (LCD DATA) HI BYTE MOVWF DISPLAY_STEP_BYTE_HI CALL MHZ1 ;DISPLAY STEP SIZE SELECTED ON LCD GOTO RTN STEP2 MOVLW .2 XORWF BUTT_COUNT,W BTFSS STATUS,Z GOTO STEP3 MOVLW b'00001100' ;100 kHz ; (100kHz/0.00833333 = 12) MOVWF STEP_BYTE_LO MOVLW b'00000000' MOVWF STEP_BYTE_HI ;100 kHz MOVLW b'01100100' ;100 kHz MOVWF DISPLAY_STEP_BYTE_LO MOVLW b'00000000' MOVWF DISPLAY_STEP_BYTE_HI CALL KHZ100 GOTO RTN STEP3 MOVLW .3 XORWF BUTT_COUNT,W BTFSS STATUS,Z GOTO RTN MOVLW b'00000001' ;8.33kHz ;0ne frequency step MOVWF STEP_BYTE_LO MOVLW b'00000000' MOVWF STEP_BYTE_HI MOVLW b'00001000' ;8.33 kHz MOVWF DISPLAY_STEP_BYTE_LO MOVLW b'00000000' MOVWF DISPLAY_STEP_BYTE_HI CALL KHZ8.3 RTN RETURN ;******************************************************************************************* SEND_LCD CALL LCD_Line1 ;move to 1ST row, first column MOVLW .1 CALL LCD_CharD MOVF TenK, w ;display decimal characters CALL LCD_CharD ;using LCD_CharD to convert to ASCII MOVF Thou, w CALL LCD_CharD MOVLW '.' CALL LCD_Char MOVF Hund, w CALL LCD_CharD MOVF Tens, w CALL LCD_CharD MOVF Ones, w CALL LCD_CharD RETURN ;************************************************************************************* MHZ1 CALL LCD_Line2S CALL MHZ_STRING RETURN ;**************************************************** KHZ100 CALL LCD_Line2S CALL KHZ100_STRING RETURN ;**************************************************** KHZ8.3 CALL LCD_Line2S CALL KHZ25_STRING RETURN ;****************************************************** MEM_1 CALL LCD_LINE1_MEM CALL MEM1_STRING RETURN ;************************************************** MEM_2 CALL LCD_LINE1_MEM CALL MEM2_STRING RETURN ;********************************************** MEM_3 CALL LCD_LINE1_MEM CALL MEM3_STRING RETURN ;****************************************** MEM_4 CALL LCD_LINE1_MEM CALL MEM4_STRING RETURN ;********************************************** MEM_5 CALL LCD_LINE1_MEM CALL MEM5_STRING RETURN ;****************************************************** VFO CALL LCD_LINE1_MEM CALL VFO_STRING RETURN ;********************************************** DONE CALL LCD_Line2MS CALL DONE_STRING RETURN ;******************************************* SAVE? CALL LCD_Line2MS CALL SAVE_STRING RETURN ;**************************************************** MESSAGE_CANCELL CALL LCD_Line2MS CALL CANCELL_STRING RETURN ;************************************************* MHZ_STRING MOVLW .1 CALL LCD_CharD MOVLW 'M' CALL LCD_Char MOVLW 'H' CALL LCD_Char MOVLW 'z' CALL LCD_Char MOVLW ' ' CALL LCD_Char MOVLW ' ' CALL LCD_Char RETURN ;**************************************************** KHZ100_STRING MOVLW .1 CALL LCD_CharD MOVLW .0 CALL LCD_CharD MOVLW .0 CALL LCD_CharD MOVLW 'k' CALL LCD_Char MOVLW 'H' CALL LCD_Char MOVLW 'z' CALL LCD_Char MOVLW ' ' CALL LCD_Char RETURN ;*************************************************** KHZ25_STRING MOVLW .8 CALL LCD_CharD MOVLW '.' CALL LCD_Char MOVLW .3 CALL LCD_CharD MOVLW 'k' CALL LCD_Char MOVLW 'H' CALL LCD_Char MOVLW 'z' CALL LCD_Char MOVLW ' ' CALL LCD_Char RETURN ;***************************************************** MEM1_STRING MOVLW 'M' CALL LCD_Char MOVLW 'E' CALL LCD_Char MOVLW 'M' CALL LCD_Char MOVLW .1 CALL LCD_CharD RETURN ;********************************************************* MEM2_STRING MOVLW 'M' CALL LCD_Char MOVLW 'E' CALL LCD_Char MOVLW 'M' CALL LCD_Char MOVLW .2 CALL LCD_CharD RETURN ;*********************************************** MEM3_STRING MOVLW 'M' CALL LCD_Char MOVLW 'E' CALL LCD_Char MOVLW 'M' CALL LCD_Char MOVLW .3 CALL LCD_CharD RETURN ;************************************************ MEM4_STRING MOVLW 'M' CALL LCD_Char MOVLW 'E' CALL LCD_Char MOVLW 'M' CALL LCD_Char MOVLW .4 CALL LCD_CharD RETURN ;***************************************** MEM5_STRING MOVLW 'M' CALL LCD_Char MOVLW 'E' CALL LCD_Char MOVLW 'M' CALL LCD_Char MOVLW .5 CALL LCD_CharD RETURN ;************************************** VFO_STRING MOVLW 'V' CALL LCD_Char MOVLW 'F' CALL LCD_Char MOVLW '0' CALL LCD_Char MOVLW ' ' CALL LCD_Char RETURN ;************************************************ DONE_STRING MOVLW 'D' CALL LCD_Char MOVLW 'O' CALL LCD_Char MOVLW 'N' CALL LCD_Char MOVLW 'E' CALL LCD_Char RETURN ;************************************************* SAVE_STRING MOVLW 'S' CALL LCD_Char MOVLW 'A' CALL LCD_Char MOVLW 'V' CALL LCD_Char MOVLW 'E' CALL LCD_Char RETURN ;******************************************************* CANCELL_STRING MOVLW ' ' CALL LCD_Char MOVLW ' ' CALL LCD_Char MOVLW ' ' CALL LCD_Char MOVLW ' ' CALL LCD_Char MOVLW ' ' CALL LCD_Char RETURN ;*********************************************** ;LCD routines ;Initialise LCD LCD_Init CALL LCD_Busy ;wait for LCD MOVLW 0x20 ;Set 4 bit mode CALL LCD_Cmd MOVLW 0x28 ;Set display shift CALL LCD_Cmd MOVLW 0x06 ;Set display character mode CALL LCD_Cmd MOVLW 0x0c ;Set display on/off and cursor command CALL LCD_Cmd ;Set cursor off CALL LCD_Clr ;clear display RETURN ;************************************************************ ; command set routine LCD_Cmd MOVWF templcd SWAPF templcd,w ;send upper nibble ANDLW 0x0f ;clear upper 4 bits of W MOVWF LCD_PORT BCF LCD_RS ;RS line to 0 CALL Pulse_e ;Pulse the E line high MOVF templcd,w ;send lower nibble ANDLW 0x0f ;clear upper 4 bits of W MOVWF LCD_PORT BCF LCD_RS ;RS line to 1 CALL Pulse_e ;Pulse the E line high CALL LCD_Busy RETURN ;*************************************************************** LCD_CharD ADDLW 0x30 ;add 0x30 to convert to ASCII LCD_Char MOVWF templcd SWAPF templcd,w ;send upper nibble ANDLW 0x0f ;clear upper 4 bits of W MOVWF LCD_PORT BSF LCD_RS ;RS line to 1 CALL Pulse_e ;Pulse the E line high MOVF templcd,w ;send lower nibble ANDLW 0x0f ;clear upper 4 bits of W MOVWF LCD_PORT BSF LCD_RS ;RS line to 1 CALL Pulse_e ;Pulse the E line high CALL LCD_Busy RETURN ;******************************************************************* LCD_Busy BANKSEL TRISA ;select bank 1 MOVLW b'00001111' ;set PortA for input MOVWF TRISA ;set TRISA BANKSEL PORTA ;select bank 0 BCF LCD_RS ;set LCD for command mode BSF LCD_RW ;setup to read busy flag BSF LCD_E SWAPF LCD_PORT,w ;swap nibbles and put in W BCF LCD_E MOVWF templcd2 ;put W into temp register BSF LCD_E ;dummy read of lower nibble BCF LCD_E BTFSC templcd2,7 ;test LCD busy flag GOTO LCD_Busy ;if busy check again BCF LCD_RW BANKSEL TRISA ;set bank 1 MOVLW b'00000000' ;set Port for output MOVWF TRISA BANKSEL PORTA ;set bank 0 RETURN ;****************************************************************************** LCD_Line1 MOVLW 0x80 ;move to 1st row, first column CALL LCD_Cmd RETURN LCD_Line2 MOVLW 0xc0 ;move to 2nd row, first column CALL LCD_Cmd RETURN LCD_Line1_MHz MOVLW 0x87 ;move to 1st row, column 7 CALL LCD_Cmd RETURN LCD_Line2S MOVLW 0xc5 ;move to 2nd row, column 5 CALL LCD_Cmd RETURN LCD_Line2MS MOVLW 0xcc ;move to 2nd row, column 11 CALL LCD_Cmd RETURN LCD_CurOn MOVLW 0x0d ;Set display on/off and cursor command CALL LCD_Cmd RETURN LCD_CurOff MOVLW 0x0c ;Set display on/off and cursor command CALL LCD_Cmd RETURN LCD_Clr MOVLW 0x01 ;Clear display CALL LCD_Cmd LCD_LINE1_MEM MOVLW 0x8C CALL LCD_Cmd RETURN RETURN ;************************************************************* Pulse_e BSF LCD_E NOP BCF LCD_E RETURN ;************************************************************ ;THIS ROUTINE COPIED FROM WWW.PICLIST.COM --- WORKS ACE! ; Takes number in NumH:NumL ; Returns decimal in ; TenK:Thou:Hund:Tens:Ones CONVERT MOVFW DISPLAY_VAR_HI MOVWF CONVERT_BYTE_HI MOVFW DISPLAY_VAR_LO MOVWF CONVERT_BYTE_LO SWAPF CONVERT_BYTE_HI,W IORLW B'11110000' MOVWF Thou ADDWF Thou,f ADDLW 0XE2 MOVWF Hund ADDLW 0X32 MOVWF Ones MOVF CONVERT_BYTE_HI,W ANDLW 0X0F ADDWF Hund,f ADDWF Hund,f ADDWF Ones,f ADDLW 0XE9 MOVWF Tens ADDWF Tens,f ADDWF Tens,f SWAPF CONVERT_BYTE_LO,W ANDLW 0X0F ADDWF Tens,f ADDWF Ones,f RLF Tens,f RLF Ones,f COMF Ones,f RLF Ones,f MOVF CONVERT_BYTE_LO,W ANDLW 0X0F ADDWF Ones,f RLF Thou,f MOVLW 0X07 MOVWF TenK ; At this point, the original number is ; equal to ; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones ; if those entities are regarded as two's ; complement binary. To be precise, all of ; them are negative except TenK. Now the number ; needs to be normalized, but this can all be ; done with simple byte arithmetic. MOVLW 0X0A ; Ten Lb1: ADDWF Ones,f DECF Tens,f BTFSS 3,0 GOTO Lb1 Lb2: ADDWF Tens,f DECF Hund,f BTFSS 3,0 GOTO Lb2 Lb3: ADDWF Hund,f DECF Thou,f BTFSS 3,0 GOTO Lb3 Lb4: ADDWF Thou,f DECF TenK,f BTFSS 3,0 GOTO Lb4 RETURN ;***************************************************************************************** ;MEMORY BUTTON TEST BUTTON_TEST2 BTFSS MEM1 ;CHECK IF MEMORY RECALL SELECT BUTTON PRESSED GOTO RTN2 ;NO, SO SKIP CALL DELAY ;WAIT FOR SWITCH BOUNCE BTFSS MEM1 ;VALID PRESS SKIP NEXT INSTRUCTION GOTO RTN2 ;INVALID PRESS, GO RTN BTFSC MEM1 ;HAS BUTTON BEEN RELEASED? GOTO $-1 ;NO CALL DELAY ;YES, WAIT FOR SWITCH BOUNCE BTFSC MEM1 ;BOUNCE OVER? GOTO $-4 ;NO DECFSZ MBUTT_COUNT ;DECREMENT MBUTT_COUNT (MEMORY RECALL SELECT BUTTON COUNTER) GOTO MSTEP1 MOVLW .5 ;LOAD MBUTT_COUNT COUNTER FOR NEXT TIME MOVWF MBUTT_COUNT MSTEP1 MOVLW .1 XORWF MBUTT_COUNT,W ;COMPARE NUMBER OF BUTTON PRESSES BTFSS STATUS,Z ;XOR RESULT ZERO SO SKIP NEXT INSTRUCTION GOTO MSTEP2 ;XOR RESULT NOT ZERO SO GOTO NEXT MEMORY STEP MOVLW 0x08 MOVWF F_EE_ADR_LO ;RECALL MEMORY LOCATION FREQUENCY WORD LO BYTE ADDRESS MOVLW 0x09 MOVWF F_EE_ADR_HI ;RECALL MEMORY LOCATION FREQUENCY WORD HI BYTE ADDRESS MOVLW 0x48 MOVWF D_EE_ADR_LO ;RECALL MEMORY LOCATION DISPLAY WORD LO BYTE ADDRESS MOVLW 0x49 MOVWF D_EE_ADR_HI ;RECALL MEMORY LOCATION DISPLAY WORD HI BYTE ADDRESS CALL FREQ_EREAD ;READ FREQUENCY WORD CALL DISP_EREAD ;READ DISPLAY WORD CALL SERIAL ;SEND FREQUENCY WORD TO SYNTH CHIP CALL SEND_LCD ;SEND DISPLAY WORD TO LCD CALL MEM_4 CALL LFU_SAVE ;SAVE FREQUENY AND DISPLAY WORDS TO EPROM BOOT UP MEMORY LOCATION GOTO RTN2 MSTEP2 MOVLW .2 XORWF MBUTT_COUNT,W ;COMPARE NUMBER OF BUTTON PRESSES BTFSS STATUS,Z ;XOR RESULT ZERO SO SKIP NEXT INSTRUCTION GOTO MSTEP3 MOVLW 0x06 MOVWF F_EE_ADR_LO MOVLW 0x07 MOVWF F_EE_ADR_HI MOVLW 0x46 MOVWF D_EE_ADR_LO MOVLW 0x47 MOVWF D_EE_ADR_HI CALL FREQ_EREAD CALL DISP_EREAD CALL SERIAL CALL SEND_LCD CALL MEM_3 CALL LFU_SAVE GOTO RTN2 MSTEP3 MOVLW .3 XORWF MBUTT_COUNT,W ;COMPARE NUMBER OF BUTTON PRESSES BTFSS STATUS,Z ;XOR RESULT ZERO SO SKIP NEXT INSTRUCTION GOTO MSTEP4 MOVLW 0x04 MOVWF F_EE_ADR_LO MOVLW 0x05 MOVWF F_EE_ADR_HI MOVLW 0x44 MOVWF D_EE_ADR_LO MOVLW 0x45 MOVWF D_EE_ADR_HI CALL FREQ_EREAD CALL DISP_EREAD CALL SERIAL CALL SEND_LCD CALL MEM_2 CALL LFU_SAVE GOTO RTN2 MSTEP4 MOVLW .4 XORWF MBUTT_COUNT,W ;COMPARE NUMBER OF BUTTON PRESSES BTFSS STATUS,Z ;XOR RESULT ZERO SO SKIP NEXT INSTRUCTION GOTO MSTEP5 MOVLW 0x02 MOVWF F_EE_ADR_LO MOVLW 0x03 MOVWF F_EE_ADR_HI MOVLW 0x42 MOVWF D_EE_ADR_LO MOVLW 0x43 MOVWF D_EE_ADR_HI CALL FREQ_EREAD CALL DISP_EREAD CALL SERIAL CALL SEND_LCD CALL MEM_1 CALL LFU_SAVE GOTO RTN2 MSTEP5 MOVLW .5 XORWF MBUTT_COUNT,W ;COMPARE NUMBER OF BUTTON PRESSES BTFSS STATUS,Z ;XOR RESULT ZERO SO SKIP NEXT INSTRUCTION GOTO RTN2 MOVLW 0x0a MOVWF F_EE_ADR_LO MOVLW 0x0b MOVWF F_EE_ADR_HI MOVLW 0x4a MOVWF D_EE_ADR_LO MOVLW 0x4b MOVWF D_EE_ADR_HI CALL FREQ_EREAD CALL DISP_EREAD CALL SERIAL CALL SEND_LCD CALL LFU_SAVE CALL MEM_5 RTN2 RETURN ;*********************************************************************************************** FREQ_EREAD MOVF F_EE_ADR_LO,W BANKSEL TRISA ; Bank 1 Selected MOVWF EEADR ; Set location to read EEPROM from BSF EECON1, RD ; Enables EEPROM read BTFSC EECON1, RD GOTO $-1 MOVF EEDATA, W ; Load working resgister with EEPROM data BANKSEL PORTA ; Bank 0 Selected MOVWF VAR_LO MOVF F_EE_ADR_HI,W BANKSEL TRISA ; Bank 1 Selected MOVWF EEADR ; Set location to read EEPROM from BSF EECON1, RD ; Enables EEPROM read BTFSC EECON1, RD GOTO $-1 MOVF EEDATA, W ; Load working resgister with EEPROM data BANKSEL PORTA ; Bank 0 Selected MOVWF VAR_HI RETURN ; return from where left off ;*********************************************************************************************** DISP_EREAD MOVF D_EE_ADR_LO,W BANKSEL TRISA ; Bank 1 Selected MOVWF EEADR ; Set location to read EEPROM from BSF EECON1, RD ; Enables EEPROM read BTFSC EECON1, RD GOTO $-1 MOVF EEDATA, W ; Load working resgister with EEPROM data BANKSEL PORTA ; Bank 0 Selected MOVWF DISPLAY_VAR_LO MOVF D_EE_ADR_HI,W BANKSEL TRISA ; Bank 1 Selected MOVWF EEADR ; Set location to read EEPROM from BSF EECON1, RD ; Enables EEPROM read BTFSC EECON1, RD GOTO $-1 MOVF EEDATA, W ; Load working resgister with EEPROM data BANKSEL PORTA ; Bank 0 Selected MOVWF DISPLAY_VAR_HI RETURN ; return from where left off ;********************************************************************************************* ;MEMORY SELECT ROUTINE BUTTON_TEST3 BTFSS MEM2 ;CHECK IF MEMORY SELECT LOCATION SAVE BUTTON PRESSED GOTO RTN3 ;NO, SO GO TO RTN3 CALL DELAY ;WAIT FOR SWITCH BOUNCE BTFSS MEM2 ;VALID PRESS SKIP NEXT INSTRUCTION GOTO RTN3 ;INVALID PRESS, GO TO RTN3 BTFSC MEM2 ;HAS BUTTON BEEN RELEASED? GOTO $-1 ;NO CALL DELAY ;YES, WAIT FOR SWITCH BOUNCE BTFSC MEM2 ;BOUNCE OVER? GOTO $-4 ;NO DECFSZ MS_BUTT_COUNT ;DECREMENT MEMORY SELECT SAVE BUTTON COUNTER GOTO M_SELECT1 MOVLW .5 ;LOAD COUNTER FOR NEXT TIME MOVWF MS_BUTT_COUNT M_SELECT1 MOVLW .1 XORWF MS_BUTT_COUNT,W ; HOW MANY TIMES HAS MEMORY SELECT SAVE BUTTON BTFSS STATUS,Z GOTO M_SELECT2 MOVLW 0x08 MOVWF F_EE_ADR_LO MOVLW 0x09 MOVWF F_EE_ADR_HI MOVLW 0x48 MOVWF D_EE_ADR_LO MOVLW 0x49 MOVWF D_EE_ADR_HI CALL MEM_4 GOTO SAVE M_SELECT2 MOVLW .2 XORWF MS_BUTT_COUNT,W BTFSS STATUS,Z GOTO M_SELECT3 MOVLW 0x06 MOVWF F_EE_ADR_LO MOVLW 0x07 MOVWF F_EE_ADR_HI MOVLW 0x46 MOVWF D_EE_ADR_LO MOVLW 0x47 MOVWF D_EE_ADR_HI CALL MEM_3 GOTO SAVE M_SELECT3 MOVLW .3 XORWF MS_BUTT_COUNT,W BTFSS STATUS,Z GOTO M_SELECT4 MOVLW 0x04 MOVWF F_EE_ADR_LO MOVLW 0x05 MOVWF F_EE_ADR_HI MOVLW 0x44 MOVWF D_EE_ADR_LO MOVLW 0x45 MOVWF D_EE_ADR_HI CALL MEM_2 GOTO SAVE M_SELECT4 MOVLW .4 XORWF MS_BUTT_COUNT,W BTFSS STATUS,Z GOTO M_SELECT5 MOVLW 0x02 MOVWF F_EE_ADR_LO MOVLW 0x03 MOVWF F_EE_ADR_HI MOVLW 0x42 MOVWF D_EE_ADR_LO MOVLW 0x43 MOVWF D_EE_ADR_HI CALL MEM_1 GOTO SAVE M_SELECT5 MOVLW .5 XORWF MS_BUTT_COUNT,W BTFSS STATUS,Z GOTO RTN3 MOVLW 0x0a MOVWF F_EE_ADR_LO MOVLW 0x0b MOVWF F_EE_ADR_HI MOVLW 0x4a MOVWF D_EE_ADR_LO MOVLW 0x4b MOVWF D_EE_ADR_HI CALL MEM_5 SAVE CALL SAVE? CALL SAVE_BUTTON_TEST RTN3 RETURN ;******************************************************************************************** SAVE_BUTTON_TEST CALL SAVE_DELAY BTFSS MEM3 ;CHECK IF DONE (SAVE) BUTTON PRESSED GOTO RTN4 ;NO, SO GOTO RTN4 CALL DELAY ;WAIT FOR SWITCH BOUNCE BTFSS MEM3 ;VALID PRESS SKIP NEXT INSTRUCTION GOTO RTN4 ;INVALID PRESS, RTN4 CALL SAVE_FREQ ;SAVE FREQUENCY CALL SAVE_DISP ;SAVE DISPLAY CALL DONE CALL SAVE_DELAY RTN4 CALL MESSAGE_CANCELL RETURN ;*********************************************************************************** LFU_SAVE ; LAST FREQUENCY USED SAVE ROUTINE MOVLW 0x00 ; MOVWF F_EE_ADR_LO ;BOOT UP FREQUENCY WORD EPROM ADDRESS LO BYTE MOVLW 0x01 ; MOVWF F_EE_ADR_HI ;BOOT UP FREQUENCY WORD EPROM ADDRESS HI BYTE ; MOVLW 0x40 ;BOOT UP FREQUENCY DISPLAY WORD EPROM ADDRESS HI BYTE MOVWF D_EE_ADR_LO ; MOVLW 0x41 ;BOOT UP FREQUENCY DISPLAY WORD EPROM ADDRESS HI BYTE MOVWF D_EE_ADR_HI CALL SAVE_FREQ CALL SAVE_DISP RETURN ;********************************************************************************************* SAVE_FREQ MOVF F_EE_ADR_LO,W ; Load working register with ee_adr BANKSEL TRISA ; Bank 1 Selected MOVWF EEADR ; Set location to write to EEPROM BANKSEL PORTA ; Bank 0 Selected MOVF VAR_LO,W ; Load working register with ee_data BANKSEL TRISA ; Bank 1 Selected MOVWF EEDATA ; Data to be written to address BSF EECON1, WREN ; Enables EEPROM write ; The next four lines must be there to allow the data to be written MOVLW d'85' ; Load working register with decimal 85 MOVWF EECON2 ; Load working register to EECON2 MOVLW d'170' ; Load working register with decimal 170 MOVWF EECON2 ; Load working register to EECON2 BSF EECON1, WR ; write data BTFSC EECON1, WR ; has data write completed? GOTO $-1 ; If 1, check again, 0 indicates data written BCF EECON1, WREN ; Turn off EEPROM write BANKSEL PORTA ; Select bank 0 MOVF F_EE_ADR_HI,W ; Load working register with ee_adr BANKSEL TRISA ; Bank 1 Selected MOVWF EEADR ; Set location to write to EEPROM BANKSEL PORTA ; Bank 0 Selected MOVF VAR_HI,W ; Load working register with ee_data BANKSEL TRISA ; Bank 1 Selected MOVWF EEDATA ; Data to be written to address BSF EECON1, WREN ; Enables EEPROM write ; The next four lines must be there to allow the data to be written MOVLW d'85' ; Load working register with decimal 85 MOVWF EECON2 ; Load working register to EECON2 MOVLW d'170' ; Load working register with decimal 170 MOVWF EECON2 ; Load working register to EECON2 BSF EECON1, WR ; WRITE data BTFSC EECON1, WR GOTO $-1 ; If 1, check again, 0 indicates data written BCF EECON1, WREN ; Turn off EEPROM write BANKSEL PORTA ; Select bank 0 RETURN ;************************************************************************************************* SAVE_DISP MOVF D_EE_ADR_LO,W ; Load working register with ee_adr BANKSEL TRISA ; Bank 1 Selected MOVWF EEADR ; Set location to write to EEPROM BANKSEL PORTA ; Bank 0 Selected MOVF DISPLAY_VAR_LO,W ; Load working register with ee_data BANKSEL TRISA ; Bank 1 Selected MOVWF EEDATA ; Data to be written to address BSF EECON1, WREN ; Enables EEPROM write ; The next four lines must be there to allow the data to be written MOVLW d'85' ; Load working register with decimal 85 MOVWF EECON2 ; Load working register to EECON2 MOVLW d'170' ; Load working register with decimal 170 MOVWF EECON2 ; Load working register to EECON2 BSF EECON1, WR ; Send data BTFSC EECON1, WR GOTO $-1 ; If 1, check again, 0 indicates data written BCF EECON1, WREN ; Turn off EEPROM write BANKSEL PORTA ; Select bank 0 MOVF D_EE_ADR_HI,W ; Load working register with ee_adr BANKSEL TRISA ; Bank 1 Selected MOVWF EEADR ; Set location to write to EEPROM BANKSEL PORTA ; Bank 0 Selected MOVF DISPLAY_VAR_HI,W ; Load working register with ee_data BANKSEL TRISA ; Bank 1 Selected MOVWF EEDATA ; Data to be written to address BSF EECON1, WREN ; Enables EEPROM write ; The next four lines must be there to allow the data to be written MOVLW d'85' ; Load working register with decimal 85 MOVWF EECON2 ; Load working register to EECON2 MOVLW d'170' ; Load working register with decimal 170 MOVWF EECON2 ; Load working register to EECON2 BSF EECON1, WR ; Send data BTFSC EECON1, WR GOTO $-1 ; If 1, check again, 0 indicates data written BCF EECON1, WREN ; Turn off EEPROM write BANKSEL PORTA ; Select bank 0 RETURN ;************************************************************************************************* ; SYNTHESISER CHIP INISILIZATION AS PER MANUFACTER DATA SHEET IN_MC BCF LATCH BSF LATCH BCF CLOCK BCF SDATA NOP NOP BSF CLOCK BCF CLOCK BSF CLOCK BCF CLOCK BSF CLOCK BCF CLOCK BSF CLOCK BCF CLOCK NOP NOP BCF LATCH BSF CLOCK BCF CLOCK BSF CLOCK BCF CLOCK BSF CLOCK BCF CLOCK BSF SDATA NOP BSF CLOCK BCF CLOCK BCF SDATA BSF CLOCK BCF CLOCK BSF LATCH CALL Delay100 RETURN ;************************************************************************ Delay3 ;70uS DELAY MOVLW .17 MOVWF dly_count3 LOOP5 DECFSZ dly_count3,1 GOTO LOOP5 RETURN ;******************************************************************************* Delay100 ;100mS DELAY MOVLW .200 MOVWF dly_count4 MOVLW .130 MOVWF dly_count5 LOOP100 DECFSZ dly_count4,1 GOTO LOOP100 DECFSZ dly_count5,1 GOTO LOOP100 RETURN ;*********************************************************************************** DELAY ;38mS DELAY FOR SWITCH BOUNCE MOVLW .100 MOVWF DLY_COUNT1 MOVLW .50 MOVWF DLY_COUNT2 LOOP DECFSZ DLY_COUNT1,1 GOTO LOOP DECFSZ DLY_COUNT2,1 GOTO LOOP RETURN ;********************************************************************** SAVE_DELAY ;2.2 SECOND DELAY FOR MEMORY SAVE MOVLW .100 MOVWF DLY_COUNT6 MOVLW .100 MOVWF DLY_COUNT7 MOVLW .12 MOVWF DLY_COUNT8 LOOP6 DECFSZ DLY_COUNT6,1 GOTO LOOP6 DECFSZ DLY_COUNT7,1 GOTO LOOP6 DECFSZ DLY_COUNT8,1 GOTO LOOP6 RETURN ;****************************************************************************** END